package com.datasure.application.service.impl;

import com.datasure.application.req.command.DeviceRegisterCommand;
import com.datasure.application.res.assembler.DeviceEntityAssembler;
import com.datasure.application.service.SourceUninstallService;
import com.datasure.domain.entity.Device;
import com.datasure.domain.entity.DeviceEx;
import com.datasure.domain.entity.DiskClone;
import com.datasure.domain.service.SourceDeviceDomainService;
import com.datasure.external.SourceDeviceRemoteService;
import com.datasure.repository.DeviceExRepository;
import com.datasure.repository.DeviceRepository;
import com.datasure.repository.DiskCloneRepository;
import com.datasure.types.IntegerId;
import com.datasure.types.LongId;
import com.datasure.types.StringId;

import javax.xml.bind.ValidationException;
import java.util.List;
import java.util.Objects;

/**
 * @author zhangxiaolong
 * @ClassName DeviceServiceImpl.java
 * @Description
 * @createTime 2022年01月14日 13:45:00
 */
public class SourceUninstallServiceImpl implements SourceUninstallService {

    private DeviceEntityAssembler deviceEntityAssembler;

    private DeviceRepository deviceRepository;
    private DeviceExRepository deviceExRepository;
    private DiskCloneRepository diskCloneRepository;
    private SourceDeviceRemoteService remoteService;

    private SourceDeviceDomainService sourceDeviceDomainService;

    // TODO: 2022/1/14 统一注入 ，使用spring扩展
    public SourceUninstallServiceImpl(DeviceRepository deviceRepository) {
        this.deviceRepository = deviceRepository;
        deviceEntityAssembler = DeviceEntityAssembler.INSTANCE;
    }

    /**
     * 新设备信息注册
     * @param registerCommand
     * @throws ValidationException
     */
    public void register(DeviceRegisterCommand registerCommand) throws ValidationException {
        final Device device = deviceEntityAssembler.toDeviceFromSaveCommand(registerCommand);
        final DeviceEx deviceEx = deviceEntityAssembler.toDeviceExFromSaveCommand(registerCommand);

        //根据device_unique_id查询设备
        //final Device findDevice = deviceRepository.find(device.getId());
        //设备注册
        device.register(sourceDeviceDomainService);

        //持久化到数据库
        deviceRepository.save(device);
        deviceExRepository.save(deviceEx);

    }

    /**
     * 设备上线
     * @param deviceUniqueId
     */
    public void onLine(StringId deviceUniqueId){
        final Device device = Device.builder()
                .deviceUniqueId(deviceUniqueId)
                .build();
        //设备上线
        device.onLine();

        //持久化到数据库
        deviceRepository.save(device);
    }

    /**
     * 根据设备id卸载源端设备
     * @param deviceId
     */
    public void uninstall(IntegerId deviceId) throws ValidationException{

//        final Device device = deviceRepository.find(deviceId);
//        DiskClone diskClone = diskCloneRepository.findByDeviceId(deviceId);
//        //判断是否关联任务
//        if(Objects.nonNull(diskClone)){
//            throw new ValidationException("设备被绑定，无法卸载。");
//        }
//
//        //调用远程脚本卸载客户端；异步的
//        String uninstallResult = sourceUninstallService.uninstall(device);
//
//        //todo 操作日志记录（正常日志、异常日志）
//
//        //持久化数据库
//        deviceRepository.save(device);

    }

    /**
     * 批量卸载源端设备
     * @param deviceIds
     */
    public void batchUninstall(List<IntegerId> deviceIds) throws ValidationException{
        for(IntegerId deviceId: deviceIds){

            final Device device = deviceRepository.find(deviceId);
            DiskClone diskClone = diskCloneRepository.findByDeviceId(deviceId);
            //判断是否关联任务
            if(Objects.nonNull(diskClone)){
                throw new ValidationException("设备被绑定，无法卸载。");
            }

            //调用远程脚本卸载客户端；异步执行
            //@Async
            uninstallDetailHandle(device);

            //todo 操作日志记录（正常日志、异常日志）

        }

    }

    /**
     * 根据设备唯一识别号卸载设备
     * @param deviceUniqueId
     */
    public void uninstall(StringId deviceUniqueId){

    }

    /**
     * 1.卸载源端远程处理
     * 2.卸载结果持久化到数据库
     * todo 数据库事务
     * @param device
     */
    private void uninstallDetailHandle(Device device){
        String uninstallRes = remoteService.uninstall(device);
        device.uninstallDesc(uninstallRes);

        //卸载设备
        device.uninstall();

        deviceRepository.save(device);
        deviceExRepository.save(DeviceEx.builder().build());
        // TODO: 2022/2/8  .......数据持久化

    }

}
